package edu.bjtu.supplychain.client;


import edu.bjtu.supplychain.common.CommonClient;
import edu.bjtu.supplychain.contract.SuppleChain;
import edu.bjtu.supplychain.contract.SupplyChainDev1;
import edu.bjtu.supplychain.entity.*;
import edu.bjtu.supplychain.utils.SpringUtils;
import org.fisco.bcos.sdk.BcosSDK;
import org.fisco.bcos.sdk.abi.datatypes.generated.tuples.generated.Tuple5;
import org.fisco.bcos.sdk.abi.datatypes.generated.tuples.generated.Tuple6;
import org.fisco.bcos.sdk.abi.datatypes.generated.tuples.generated.Tuple7;
import org.fisco.bcos.sdk.model.TransactionReceipt;
import org.fisco.bcos.sdk.transaction.model.exception.ContractException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Service;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

/**
 * @Classname CRUDClient
 * @Description sdk客户端，可以不使用ApplicationRunner，这里是让spring容器启动部署合约
 * @Date 2021/3/25 21:45
 * @Created by zyt
 */
@Service
public class CRUDClient extends CommonClient implements ApplicationRunner {

    public static final Logger logger = LoggerFactory.getLogger(CRUDClient.class.getName());

    public void insertSeed(SeedFactory seedFactory){
        SupplyChainDev1 contract = (SupplyChainDev1) getContractMap().get("SupplyChainDev1");
        TransactionReceipt receipt = contract.insertSeed(seedFactory.getFactoryCode(), seedFactory.getSeedId(), seedFactory.getSeedName(), seedFactory.getOrigin(), seedFactory.getQuality(), seedFactory.getBrand(), seedFactory.getLogTime());
        logger.info("调用SupplyChainDev01的insertSeed方法");
        logger.info("调用结果: {}", receipt);
    }

    public List<SeedFactory> selectSeed(String factoryCode) throws ContractException {
        logger.info("调用了SupplyChainDev1的selectSeed方法");
        SupplyChainDev1 contract = (SupplyChainDev1) getContractMap().get("SupplyChainDev1");
        BigInteger entriesSize = contract.selectSize("t_seed_dev1", factoryCode);
        int size = entriesSize.intValue();
        if(size == 0) {
            logger.info("没有查到数据");
            return new ArrayList<>();
        } else {
            List<SeedFactory> seedFactories = new LinkedList<>();
            for (int i = 0;i < size; i++) {
                Tuple6<String, String, String, String, String, String> tuple = contract.selectSeed(factoryCode, new BigInteger(Integer.toString(i)));
                SeedFactory seedFactory = new SeedFactory(factoryCode,tuple.getValue1(),tuple.getValue2(),tuple.getValue3(),tuple.getValue4(),tuple.getValue5(),tuple.getValue6());
                seedFactories.add(seedFactory);
            }
            logger.info("查到了: {}个数据", seedFactories.size());
            return seedFactories;
        }
    }

    public void insertFarm(Farm farm){
        SupplyChainDev1 contract = (SupplyChainDev1) getContractMap().get("SupplyChainDev1");
        TransactionReceipt receipt = contract.insertFarm(farm.getFactoryCode(),farm.getCropId(),farm.getSeedId(),farm.getCropName(),farm.getReapTime(),farm.getSponsor(),farm.getLogTime());
        logger.info("调用SupplyChainDev01的insertFarm方法");
        logger.info("调用结果: {}", receipt);
    }

    public List<Farm> selectFarm(String factoryCode) throws ContractException {
        logger.info("调用了SupplyChainDev1的selectFarm方法");
        SupplyChainDev1 contract = (SupplyChainDev1) getContractMap().get("SupplyChainDev1");
        BigInteger entriesSize = contract.selectSize("t_farm_dev1", factoryCode);
        int size = entriesSize.intValue();
        if(size == 0) {
            logger.info("没有查到数据");
            return new ArrayList<>();
        } else {
            List<Farm> farms = new LinkedList<>();
            for (int i = 0;i < size; i++) {
                Tuple6<String, String, String, String, String, String> tuple = contract.selectFarm(factoryCode, new BigInteger(Integer.toString(i)));
                Farm farm = new Farm(factoryCode,tuple.getValue1(),tuple.getValue2(),tuple.getValue3(),tuple.getValue4(),tuple.getValue5(),tuple.getValue6());
                farms.add(farm);
            }
            logger.info("查到了: {}个数据", farms.size());
            return farms;
        }
    }

    public void insertPlant(Plant plant){
        SupplyChainDev1 contract = (SupplyChainDev1) getContractMap().get("SupplyChainDev1");
        TransactionReceipt receipt = contract.insertPlant(plant.getFactoryCode(), plant.getProductId(),plant.getCropId(),plant.getArrivalTime(),plant.getOutTime(),plant.getQuality(),plant.getSponsor(),plant.getLogTime());
        logger.info("调用SupplyChainDev01的insertPlant方法");
        logger.info("调用结果: {}", receipt);
    }

    public List<Plant> selectPlant(String factoryCode) throws ContractException {
        logger.info("调用了SupplyChainDev1的selectPlant方法");
        SupplyChainDev1 contract = (SupplyChainDev1) getContractMap().get("SupplyChainDev1");
        BigInteger entriesSize = contract.selectSize("t_plant_dev1", factoryCode);
        int size = entriesSize.intValue();
        if(size == 0) {
            logger.info("没有查到数据");
            return new ArrayList<>();
        } else {
            List<Plant> plants = new LinkedList<>();
            for (int i = 0;i < size; i++) {
                Tuple7<String, String, String, String, String, String, String> tuple = contract.selectPlant(factoryCode, new BigInteger(Integer.toString(i)));
                Plant plant = new Plant(factoryCode,tuple.getValue1(),tuple.getValue2(),tuple.getValue3(),tuple.getValue4(),tuple.getValue5(),tuple.getValue6(),tuple.getValue7());
                plants.add(plant);
            }
            logger.info("查到了: {}个数据", plants.size());
            return plants;
        }
    }

    public void insertInspect(Inspect inspect){
        SupplyChainDev1 contract = (SupplyChainDev1) getContractMap().get("SupplyChainDev1");
        TransactionReceipt receipt = contract.insertInspect(inspect.getFactoryCode(),inspect.getCropId(),inspect.getProductId(),inspect.getInspectTime(),inspect.getInspectResult(),inspect.getInspectSponsor(),inspect.getLogTime());
        logger.info("调用SupplyChainDev01的insertInspect方法");
        logger.info("调用结果: {}", receipt);
    }

    public List<Inspect> selectInspect(String factoryCode) throws ContractException {
        logger.info("调用了SupplyChainDev1的selectInspect方法");
        SupplyChainDev1 contract = (SupplyChainDev1) getContractMap().get("SupplyChainDev1");
        BigInteger entriesSize = contract.selectSize("t_inspect_dev1", factoryCode);
        int size = entriesSize.intValue();
        if(size == 0) {
            logger.info("没有查到数据");
            return new ArrayList<>();
        } else {
            List<Inspect> inspects = new LinkedList<>();
            for (int i = 0;i < size; i++) {
                Tuple6<String, String, String, String, String, String> tuple = contract.selectInspect(factoryCode, new BigInteger(Integer.toString(i)));
                Inspect inspect = new Inspect(factoryCode, tuple.getValue1(),tuple.getValue2(),tuple.getValue3(),tuple.getValue4(),tuple.getValue5(),tuple.getValue6());
                inspects.add(inspect);
            }
            logger.info("查到了: {}个数据", inspects.size());
            return inspects;
        }
    }

    public void insertButcher(Butcher butcher){
        SupplyChainDev1 contract = (SupplyChainDev1) getContractMap().get("SupplyChainDev1");
        TransactionReceipt receipt = contract.insertButcher(butcher.getFactoryCode(),butcher.getProductId(),butcher.getArrivalTime(),butcher.getOutTime(),butcher.getSponsor(),butcher.getLogTime());
        logger.info("调用SupplyChainDev01的insertButcher方法");
        logger.info("调用结果: {}", receipt);
    }

    public List<Butcher> selectButcher(String factoryCode) throws ContractException {
        logger.info("调用了SupplyChainDev1的selectButcher方法");
        SupplyChainDev1 contract = (SupplyChainDev1) getContractMap().get("SupplyChainDev1");
        BigInteger entriesSize = contract.selectSize("t_butcher_dev1", factoryCode);
        int size = entriesSize.intValue();
        if(size == 0) {
            logger.info("没有查到数据");
            return new ArrayList<>();
        } else {
            List<Butcher> butchers = new LinkedList<>();
            for (int i = 0;i < size; i++) {
                Tuple5<String, String, String, String, String> tuple = contract.selectButcher(factoryCode, new BigInteger(Integer.toString(i)));
                Butcher butcher = new Butcher(factoryCode,tuple.getValue1(),tuple.getValue2(),tuple.getValue3(),tuple.getValue4(),tuple.getValue5());
                butchers.add(butcher);
            }
            logger.info("查到了: {}个数据", butchers.size());
            return butchers;
        }
    }

    public void insertCarrier(Carrier carrier){
        SupplyChainDev1 contract = (SupplyChainDev1) getContractMap().get("SupplyChainDev1");
        TransactionReceipt receipt = contract.insertCarrier(carrier.getFactoryCode(),carrier.getProductId(),carrier.getDeliverAddress(),carrier.getDeliverTime(),carrier.getReceiveAddress(),carrier.getReceiveTime(),carrier.getApproachMsg(),carrier.getLogTime());
        logger.info("调用SupplyChainDev01的insertCarrier方法");
        logger.info("调用结果: {}", receipt);
    }

    public List<Carrier> selectCarrier(String factoryCode) throws ContractException {
        logger.info("调用了SupplyChainDev1的selectCarrier方法");
        SupplyChainDev1 contract = (SupplyChainDev1) getContractMap().get("SupplyChainDev1");
        BigInteger entriesSize = contract.selectSize("t_carrier_dev1", factoryCode);
        int size = entriesSize.intValue();
        if(size == 0) {
            logger.info("没有查到数据");
            return new ArrayList<>();
        } else {
            List<Carrier> carriers = new LinkedList<>();
            for (int i = 0;i < size; i++) {
                Tuple7<String, String, String, String, String, String, String> tuple = contract.selectCarrier(factoryCode, new BigInteger(Integer.toString(i)));
                Carrier carrier = new Carrier(factoryCode,tuple.getValue1(),tuple.getValue2(),tuple.getValue3(),tuple.getValue4(),tuple.getValue5(),tuple.getValue6(),tuple.getValue7());
                carriers.add(carrier);
            }
            logger.info("查到了: {}个数据", carriers.size());
            return carriers;
        }
    }

    public void insertTerminal(Terminal terminal){
        SupplyChainDev1 contract = (SupplyChainDev1) getContractMap().get("SupplyChainDev1");
        TransactionReceipt receipt = contract.insertTerminal(terminal.getFactoryCode(),terminal.getProductId(),terminal.getSellTime(),terminal.getBrandName(),terminal.getProductType(),terminal.getLogTime());
        logger.info("调用SupplyChainDev01的insertTerminal方法");
        logger.info("调用结果: {}", receipt);
    }

    public List<Terminal> selectTerminal(String factoryCode) throws ContractException {
        logger.info("调用了SupplyChainDev1的selectTerminal方法");
        SupplyChainDev1 contract = (SupplyChainDev1) getContractMap().get("SupplyChainDev1");
        BigInteger entriesSize = contract.selectSize("t_terminal_dev1", factoryCode);
        int size = entriesSize.intValue();
        if(size == 0) {
            logger.info("没有查到数据");
            return new ArrayList<>();
        } else {
            List<Terminal> terminals = new LinkedList<>();
            for (int i = 0;i < size; i++) {
                Tuple5<String, String, String, String, String> tuple = contract.selectTerminal(factoryCode, new BigInteger(Integer.toString(i)));
                Terminal terminal = new Terminal(factoryCode, tuple.getValue1(),tuple.getValue2(), tuple.getValue3(),tuple.getValue4(),tuple.getValue5());
                terminals.add(terminal);
            }
            logger.info("查到了: {}个数据", terminals.size());
            return terminals;
        }
    }
    /*
    public void edit(String name, String age, String tel) {

        TestCRUD testCRUD = (TestCRUD) getContractMap().get("TestCRUD");
        TransactionReceipt receipt = testCRUD.update(name, age, tel);
        logger.info("调用CRUDClient的edit方法");
        logger.info("结果：{}", receipt);

    }
*/
    @Override
    public void remove(String name) {
        logger.info("执行了remove方法");
    }

    @Override
    public void run(ApplicationArguments args) throws Exception {
        BcosSDK sdk = SpringUtils.getBean("bcosSDK");
        deploy("SupplyChainDev1", SupplyChainDev1.class, sdk, 1);
    }
}
